/* 
    React.createPorstal(child,container):将当前组件或element 元素节点 渲染到组件之外的地方
    组件静态方法的使用
    不依赖父组件实现挂载/卸载组件
*/
import React, { useMemo, useEffect, useState } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
/* 控制弹窗隐藏动画效果 */
const controlShow = (f1, f2, value, timer) => {
	f1(value)
	return setTimeout(() => {
		f2(value)
	}, timer)
}

export default function Dialog(props) {
	const { width, visible, closeCb, onClose } = props
	/* 控制 modelShow 动画效果  */
	const [modelShow, setModelShow] = useState(visible) // 控制显示/隐藏
	const [modelShowAync, setModelShowAync] = useState(visible) // 控制动画执行
	/* 防止函数组件没一次都执行createPortal */
	const renderChildren = useMemo(() => {
		/* 把元素渲染到组件之外呢的 document.body 上 */
		return ReactDOM.createPortal(
			<div
				style={{ display: modelShow ? 'block' : 'none' }}
				className="model-container"
			>
				<div
					className="model-wrap"
					style={{ opacity: modelShowAync ? 1 : 0 }}
				>
					<div style={{ width: width + 'px' }}>{props.children}</div>
				</div>
				<div
					onClick={() => {
						onClose?.()
					}}
					className="model-container mast"
					style={{ opacity: modelShowAync ? 0.6 : 0 }}
				></div>
			</div>,
			document.body
		)
	}, [modelShow, modelShowAync])

	useEffect(() => {
		let timer
		if (visible) {
			// 打开弹窗 需要先让
			timer = controlShow(setModelShow, setModelShowAync, visible, 30)
		} else {
			timer = controlShow(setModelShowAync, setModelShow, visible, 1000)
		}

		return () => {
			timer && clearTimeout(timer)
		}
	}, [visible])
	/* 执行关闭弹窗后的回调 */
	useEffect(() => {
		!modelShow && closeCb?.()
	}, [modelShow])

	return renderChildren
}
